package com.inspur.cloud.service.dataspace;

import com.inspur.cloud.dao.dataspace.AuditLogDao;
import com.inspur.cloud.entity.dataspace.AuditLogEntity;
import com.inspur.cloud.entity.dataspace.vo.AuditLogReq;
import com.inspur.cloud.exception.ApiException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class AuditLogService {

    @Autowired
    private AuditLogDao auditLogDao;

    public void save(AuditLogEntity operationLog) {
        auditLogDao.save(operationLog);
    }

    public Page<AuditLogEntity> list(AuditLogReq reqParam, Integer pageIndex, Integer pageSize) {
        if (reqParam == null) {
            return auditLogDao.findAll(PageRequest.of(pageIndex - 1, pageSize));
        }
        Specification<AuditLogEntity> specification = (Specification<AuditLogEntity>) (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            Long beginTime = reqParam.getBeginTime();
            Long endTime = reqParam.getEndTime();
            if (beginTime != null && beginTime != 0) {
                list.add(cb.greaterThanOrEqualTo(root.get("insDate"), new Date(beginTime)));
            }
            if (endTime != null && endTime != 0) {
                list.add(cb.lessThan(root.get("insDate"), new Date(endTime)));
            }
            if (!StringUtils.isEmpty(reqParam.getMethodName())) {
                list.add(cb.equal(root.get("requestMethod"), reqParam.getMethodName()));
            }
            if (!StringUtils.isEmpty(reqParam.getUsername())) {
                list.add(cb.like(root.get("loginName"), "%" + reqParam.getUsername() + "%"));
            }
            return cb.and(list.toArray(new Predicate[list.size()]));
        };
        //分页是从0开始而不是1，所以要减1
        Sort sort = new Sort(Sort.Direction.DESC, "insDate");
        return auditLogDao.findAll(specification, PageRequest.of(pageIndex - 1, pageSize, sort));
    }

    public AuditLogEntity findById(Integer id) {
        return auditLogDao.findById(id).get();
    }

    //@Transactional
    public void deleteLog(AuditLogReq reqParam) {
        Specification<AuditLogEntity> specification = (Specification<AuditLogEntity>) (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            Long beginTime = reqParam.getBeginTime();
            Long endTime = reqParam.getEndTime();
            if (!StringUtils.isEmpty(reqParam.getIds())) {
                CriteriaBuilder.In<Integer> in = cb.in(root.get("id"));
                String[] ids = reqParam.getIds().split(",");
                for (int i = 0; i < ids.length; i++) {
                    in.value(Integer.parseInt(ids[i]));
                }
                list.add(in);
            }
            if (beginTime != null && beginTime != 0) {
                list.add(cb.greaterThanOrEqualTo(root.get("insDate"), new Date(beginTime)));
            }
            if (endTime != null && endTime != 0) {
                list.add(cb.lessThan(root.get("insDate"), new Date(endTime)));
            }
            if (!StringUtils.isEmpty(reqParam.getMethodName())) {
                list.add(cb.equal(root.get("requestMethod"), reqParam.getMethodName()));
            }
            if (!StringUtils.isEmpty(reqParam.getUsername())) {
                list.add(cb.like(root.get("loginName"), "%" + reqParam.getUsername() + "%"));
            }
            if (list.size() < 1) {
                throw new ApiException("删除条件不足");
            }
            return cb.and(list.toArray(new Predicate[list.size()]));
        };
        auditLogDao.deleteInBatch(auditLogDao.findAll(specification));
    }
}
